package org.fin.minicat.request;

import org.fin.minicat.container.Service;
import org.fin.minicat.exception.ResourceNotFoundException;
import org.fin.minicat.protocol.HttpStatusCode;
import org.fin.minicat.responce.Responce;
import org.fin.minicat.responce.ResponceUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class RequestProcessor implements Runnable {

  private final Service service;

  private final SocketChannel socket;

  public RequestProcessor(SocketChannel socket, Service service) {
    this.socket = socket;
    this.service = service;
  }

  @Override
  public void run() {
    Request request;
    Responce responce;
    try{
      int capacity = 1024;
      ByteBuffer buffer = ByteBuffer.allocate(capacity);
      int read;

      // 读取channel中的数据
      do {
        read = socket.read(buffer);

        // 如果缓冲区不足以读完所有数据，则对缓冲区进行扩容
        if (read >= buffer.capacity()) {
          ByteBuffer newBuffer = ByteBuffer.allocate(read + capacity);
          buffer.flip();
          newBuffer.put(buffer);
          buffer.clear();
          buffer = newBuffer;
        }
      } while (read != 0 && read != -1);


      // 将请求信息封装Request和Responce对象
      request = new Request(new String(buffer.array(), 0, buffer.position()));
      responce = ResponceUtils.okResponce(null);

    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    // 处理请求
    try {
      service.process(request, responce);
    }

    // 资源未找到，返回404
    catch (ResourceNotFoundException e) {
      ResponceUtils.notFoundResponce(responce);
    }

    // 其他异常，返回异常信息
    catch (Exception e) {
      responce.setContent(e.getMessage().getBytes());
      responce.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR);
      e.printStackTrace();
    }

    // 返回响应，关闭socket
    finally {
      try {
        ResponceUtils.respon(responce, socket);
        socket.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}
